﻿using System;
using System.Text;
using System.Web;
using System.Collections;
using System.Reflection;
using System.Xml;
using InfoJetSoft.Service;
using InfoJetSoft.Service.Entity;
using InfoJetSoft.Service.Util;
using InfoJetSoft.Service.Worker;

// It is ugly, but it works in most cases...

namespace InfoJetSoft.Service.Manager
{
	//InfoJet Service， InfoPath Web Form处理的入口类。
	class FormManager
	{
		//所有InfoJet Service Web Form请求的入口.
		public static InfoJetForm serviceForm(HttpContext httpContext, InfoJetContext jetContext, Hashtable paramTable)
		{
			string command = (string) paramTable[JetConstant.XDOC_PARAM_COMMAND];
			//必需有command.
			if (command == null)
			{
				InfoJetForm nullForm = new InfoJetForm( null );
				nullForm.Error = true;
				nullForm.Message = "No command.";
				return nullForm;
			}

			Form form = new Form();
			form.HttpContext = httpContext;
			form.JetContext = jetContext;
			form.ParamTable = paramTable;
            form.Command = command;

			//主要分两部分处理,Build和Update.
			if (command.StartsWith(JetConstant.CMD_BUILD_BY))
			{
				//Build是指响应结果是直接输出到页面上的.
				return buildForm( form );
			}
			else
			{
				//Update是指通过xdoc.aspx或ajax使用javascript将内容动态更新到页面上.
				return updateForm( form );
			}
		}
		
		//构造表单
		private static InfoJetForm buildForm( Form form )
		{
			if (form.Command.Equals(JetConstant.CMD_BUILD_BY_TEMPLATE)) 
			{
				//首先分配一个表单ID,作为Session中存放数据的Key.FormId将被存储在xDocForm中.
				FormSession.assignFormId( form );
				FormManager.buildFormByTemplate( form );
			}
			else if (form.Command.Equals(JetConstant.CMD_BUILD_BY_XML)) 
			{
				FormSession.assignFormId( form );
				FormManager.buildFormByXML( form );
			}
			else if (form.Command.Equals(JetConstant.CMD_BUILD_BY_MERGER)) 
			{
				FormSession.assignFormId( form );
				FormManager.buildFormByMerger( form );
			}
			else if (form.Command.Equals(JetConstant.CMD_BUILD_BY_TEMPLATEMERGER)) 
			{
				FormSession.assignFormId( form );
				FormManager.buildFormByTemplateMerger( form );
			}
			else if (form.Command.Equals(JetConstant.CMD_BUILD_BY_PARAMETERS)) 
			{
				FormSession.parseFormId( form );
				FormManager.buildFormByParameters( form );
			}
			else 
			{
				throw new InfoJetException("unsupported command: " + form.Command, "FM01");
			}
			
			//清除InfoJet Service添加的JetId.
			DOMUtil.removeJetId(form.XmlDoc);
			
			//WholeXmlDoc用于分页处理.
			if( form.WholeXmlDoc == null )
			{
				//如果没有WholeXmlDoc则使用XmlDoc.
				form.WholeXmlDoc = form.XmlDoc;
			}

			StringBuilder xmlBuffer = new StringBuilder();
			xmlBuffer.Append(DOMUtil.toString(form.XmlDoc));
			
			StringBuilder xhtmlBuffer = new StringBuilder();
			xhtmlBuffer.Append("<?xml version='1.0' encoding='UTF-8'?>");
			xhtmlBuffer.Append(DOMUtil.toString(form.HtmlDoc));

			//对Xhtml进行后处理，主要是解决一些在DOM中不能解决的<>等特殊字符问题。
			FormXhtmlPostFormatWorker.postFormatXhtml( form, xhtmlBuffer );
			
			InfoJetForm jetForm = new InfoJetForm( form );
			jetForm.Xml = xmlBuffer.ToString();
			jetForm.Xhtml = xhtmlBuffer.ToString();
			jetForm.Valid = FormIsValidateWorker.isValidate( form );

			//CID 0371 //2009.07.17 //Begin
			ScriptControlContext.Release( form );
			//CID 0371 //2009.07.17 //End

			return jetForm;
		}

		//使用temlate.xml构造InfoPath Web Form.
        private static void buildFormByTemplate(Form form)
        {
            form.XsnURI = FormUtil.getParameter(form.ParamTable, JetConstant.XDOC_PARAM_XSN_URI);
            form.Action = FormUtil.getParameter(form.ParamTable, JetConstant.XDOC_PARAM_ACTION);
            FormLoadManifestWorker.loadManifest(form);

            FormBuildXMLDocByTemplateWorker.buildXMLDocByTemplate(form);
            //CID 0042 //2008.09.08 //Begin
            FormSession.initSessionValues(form);
            //CID 0042 //2008.09.08 //End
            //CID 1990 //2013.11.09 //Begin
            UrlFields.Import(form);
            //CID 1990 //2013.11.09 //End
            FormDataLoadWorker.initDataObjectOnLoad(form);

            FormManager.buildFormView(form);
        }

		
		//从XML构造InfoPath Web Form.
		private static void  buildFormByXML(Form form)
		{
			//Xml, XsnUri, Action是必需参数。
			string xml = FormUtil.getParameter(form.ParamTable, JetConstant.XDOC_PARAM_XML);
			form.XsnURI = FormUtil.getParameter(form.ParamTable, JetConstant.XDOC_PARAM_XSN_URI);
			form.Action = FormUtil.getParameter(form.ParamTable, JetConstant.XDOC_PARAM_ACTION);
			//根据XsnUri将Manifest挂到form对象上。
			FormLoadManifestWorker.loadManifest(form);

			//构造XmlDocument。
			FormBuildXMLDocByXMLWorker.buildXMLDocByXML(form, xml);
			//CID 0042 //2008.09.08 //Begin
			FormSession.initSessionValues( form );
			//CID 0042 //2008.09.08 //End
			FormDataLoadWorker.initDataObjectOnLoad(form);

			//构造视图。
			FormManager.buildFormView(form);
		}
		
		//合并Form XML后构造表单.
		private static void  buildFormByMerger(Form form) 
		{
			form.XsnURI = FormUtil.getParameter(form.ParamTable, JetConstant.XDOC_PARAM_XSN_URI);
			form.Action = FormUtil.getParameter(form.ParamTable, JetConstant.XDOC_PARAM_ACTION);
			FormLoadManifestWorker.loadManifest(form);
			
			//应该传递两个以上的Form XML.
			FormBuildXMLDocByMergerWorker.buildXMLDocByMerger(form);
			//CID 0042 //2008.09.08 //Begin
			FormSession.initSessionValues( form );
			//CID 0042 //2008.09.08 //End
			FormDataLoadWorker.initDataObjectOnLoad(form);
			FormCodeDispatchWorker.OnAfterImport(form);

			//将CMD_BUILD_BY_MERGER转化成CMD_BUILD_BY_XML
			form.Command = JetConstant.CMD_BUILD_BY_XML;

			//构造视图.
			FormManager.buildFormView(form);
		}

		//将一个Param XML和template.xml合并.
		private static void  buildFormByTemplateMerger(Form form) 
		{
			form.XsnURI = FormUtil.getParameter(form.ParamTable, JetConstant.XDOC_PARAM_XSN_URI);
			form.Action = FormUtil.getParameter(form.ParamTable, JetConstant.XDOC_PARAM_ACTION);
			FormLoadManifestWorker.loadManifest(form);
			
			string templateXml = DOMUtil.toString( form.Manifest.Template.Doc );
			HashtableUtil.addSafety( form.ParamTable, JetConstant.XDOC_PARAM_MERGE_XML_ + "0", templateXml );

			//实际上就一个Form XML.
			FormBuildXMLDocByMergerWorker.buildXMLDocByMerger(form);
			//CID 0042 //2008.09.08 //Begin
			FormSession.initSessionValues( form );
			//CID 0042 //2008.09.08 //End
			FormDataLoadWorker.initDataObjectOnLoad(form);
			//合并动作在OnAfterImport代码中执行,由用户表单代码将ParamXml中的值写如FormXml.
			FormCodeDispatchWorker.OnAfterImport(form);

			//将CMD_BUILD_BY_TEMPLATEMERGER转化成CMD_BUILD_BY_TEMPLATE
			form.Command = JetConstant.CMD_BUILD_BY_TEMPLATE;

			//构造视图.
			FormManager.buildFormView(form);
		}

		//动态更新表单内容.
		private static InfoJetForm updateForm( Form form )
		{
			//提取表单Id,用这个表单Id从HttpSession中恢复缓存的数据.
			FormSession.parseFormId( form );
			DataWebUnauthorizedWorker.parseLoginDataObject( form );
			
			//开始根据命令分发处理.
			string updateDoc = null;
			//以下的COMMAND处理都是要通过IFRAME或AJAX替换整个xDocView.
			if (form.Command.Equals(JetConstant.CMD_UPDATE_XmlToEdit) ||        //节操作.
				form.Command.Equals(JetConstant.CMD_UPDATE_Query) ||		    //点击查询按钮.
				form.Command.Equals(JetConstant.CMD_UPDATE_New) ||			    //点击新记录按钮.
				form.Command.Equals(JetConstant.CMD_UPDATE_Refresh) ||		    //点击刷新数据按钮.
				form.Command.Equals(JetConstant.CMD_UPDATE_Submit) ||		    //点击提交表单按钮.
				form.Command.Equals(JetConstant.CMD_UPDATE_Button) ||		    //点击普通按钮.
				form.Command.Equals(JetConstant.CMD_UPDATE_View) ||		        //使用菜单切换视图.
				form.Command.Equals(JetConstant.CMD_UPDATE_Rebuild) ||          //输入数据源认证信息后重新加载表单.
			    form.Command.Equals(JetConstant.CMD_UPDATE_AddPrincipals) ||    //添加人员或组.
                form.Command.Equals(JetConstant.CMD_UPDATE_UpdatePrincipals) ||    //更新人员或组.//added by lishuchao 2011.11.10
                form.Command.Equals(JetConstant.CMD_UPDATE_DeletePrincipal) ||  //删除人员或组.
                form.Command.Equals(JetConstant.CMD_UPDATE_AddEXIItems) ||    //添加External Items.
                form.Command.Equals(JetConstant.CMD_UPDATE_DeleteEXIItem) ||       //删除External Item.
                form.Command.Equals(JetConstant.CMD_UPDATE_AddSignature) ||    //添加签名.
                form.Command.Equals(JetConstant.CMD_UPDATE_DeleteSignature) )    //删除签名.
            {
				FormManager.buildFormByParameters(form);
				updateDoc = FormServiceRefreshWorker.refresh(form);
			}
			//传送一个文件.
			else if (form.Command.Equals(JetConstant.CMD_UPDATE_File))
			{
				InfoJetForm postedFile = new InfoJetForm( null );
				postedFile.Xml = "";
				postedFile.Xhtml = PostedFileEncodeWorker.encodePostedFile( form );
				postedFile.Valid = true;
				return postedFile;
			}
			//CID 0499 //2010.03.18 //Begin
			else if (form.Command.Equals(JetConstant.CMD_UPDATE_LoadInkPictures))
			{
				InfoJetForm inkPictures = new InfoJetForm( null );
				inkPictures.Xml = "";
				inkPictures.Xhtml = InkPicturesLoadWorker.loadInkPictures( form );
				inkPictures.Valid = true;
				return inkPictures;
			}
			//CID 0499 //2010.03.18 //End
            //CID 0656 //2010.10.21 //Begin
            else if (form.Command.Equals(JetConstant.CMD_UPDATE_SearchPrincipals))
            {
                //CID 0701 //2010.11.08 //Begin
                FormLoadManifestWorker.loadManifest(form);
                //CID 0701 //2010.11.08 //End
                InfoJetForm searchPrincipals = new InfoJetForm(null);
                searchPrincipals.Xml = "";
                searchPrincipals.Xhtml = PNGSearchPrincipalsWorker.searchPrincipals(form);
                searchPrincipals.Valid = true;
                return searchPrincipals;
            }
            //CID 0656 //2010.10.21 //End
            //CID 0657 //2010.12.14 //Begin
            else if (form.Command.Equals(JetConstant.CMD_UPDATE_SearchEXIItems))
            {
                FormLoadManifestWorker.loadManifest(form);
                InfoJetForm searchItems = new InfoJetForm(null);
                searchItems.Xml = "";
                searchItems.Xhtml = EXISearchItemsWorker.searchItems(form);
                searchItems.Valid = true;
                return searchItems;
            }
            //CID 0657 //2010.12.14 //End
            //CID 0749 //2011.08.30 //Begin
            else if (form.Command.Equals(JetConstant.CMD_UPDATE_PrepareSignature))
            {
                FormLoadManifestWorker.loadManifest(form);
                InfoJetForm prepareData = new InfoJetForm(null);
                prepareData.Xml = "";
                prepareData.Xhtml = DigitalSignaturePrepareWorker.prepareSignature(form);
                prepareData.Valid = true;
                return prepareData;
            }
            //CID 0749 //2011.08.30 //End
            //CID 0749 //2011.09.23 //Begin
            else if (form.Command.Equals(JetConstant.CMD_UPDATE_ViewSignature))
            {
                FormLoadManifestWorker.loadManifest(form);
                InfoJetForm viewData = new InfoJetForm(null);
                viewData.Xml = "";
                viewData.Xhtml = DigitalSignatureViewWorker.viewSignature(form);
                viewData.Valid = true;
                return viewData;
            }
            //CID 0749 //2011.09.23 //End
            //CID 0800 //2011.03.15 //Begin
            else if (form.Command.Equals(JetConstant.CMD_UPDATE_LoadDropdownListItems))
            {
                FormLoadManifestWorker.loadManifest(form);
                FormParseRequestParamWorker.parseRequestParam(form);
                FormBuildXMLDocByFieldListWorker.buildXMLDocByFieldList(form);
                FormDataLoadWorker.reloadDataObject(form);

                InfoJetForm loadItems = new InfoJetForm(null);
                loadItems.Xml = "";
                loadItems.Xhtml = DropdownListItemsLoadWorker.loadItems(form);
                loadItems.Valid = true;
                return loadItems;
            }
            //CID 0800 //2011.03.15 //End
            else
            {
                throw new InfoJetException("unsupported command: " + form.Command, "FM02");
            }

			//在更新表单过程中,如果被设置需要关闭文档,同时清空Session.
			if( form.IsCloseDoc && (!form.IsPromptToSaveChanges) )
			{
				ClearSessionWorker.clearFormSession( form.HttpContext ); //CID 0033 //2008.06.25 //Method.
			}

			DOMUtil.removeJetId(form.XmlDoc);
			
			InfoJetForm jetForm = new InfoJetForm( form );
			jetForm.Xml = DOMUtil.toString(form.XmlDoc);
			jetForm.Xhtml = updateDoc;
			jetForm.Valid = FormIsValidateWorker.isValidate(form);

			//CID 0371 //2009.07.17 //Begin
			ScriptControlContext.Release( form );
			//CID 0371 //2009.07.17 //End

			return jetForm;
		}

		//从HTTP提交参数中重新构造表单,并执行一些在构造表单前的操作(基本上和用户在界面上的操作相关).
		private static void buildFormByParameters(Form form)
		{
			//CID 0331 //2009.07.27 //Begin
			FormLoadManifestWorker.loadManifest(form);
			FormParseRequestParamWorker.parseRequestParam(form);
			//CID 0331 //2009.07.27 //End
			FormBuildXMLDocByFieldListWorker.buildXMLDocByFieldList(form);
			
			//视图可能被修改在三个地方:用户界面选择,Rules,表单代码.
			//从界面选择会修改viewId,但是viewId除了打开表单时ParamTable中没有,以后都是存储在xDocForm中的.所以不用判断Command.
			//如果是在打开表单,则这个值是null,但是在PrepareView时遇到null会取缺省View.
			string viewId = (string) form.ParamTable[JetConstant.XDOC_PARAM_VIEW_ID];
			form.ViewId = viewId;

			if (form.Command.Equals( JetConstant.CMD_UPDATE_Rebuild ))
			{
				//目前不适合将Rebuild直接转发到BuildFormByTemplate,XML等方法中,因为很多东西都不一样,如formId等.
				//而且Rebuild还负责点Submit之后出密码框,这样似乎还不适合直接引导到BuildFormByTemplate,XML中处理.
				string rebuildCommand = (string)form.ParamTable[ JetConstant.XDOC_PARAM_REBUILD_COMMAND ];
				if( rebuildCommand != null && rebuildCommand.Length > 0 )
				{
					form.Command = rebuildCommand;
				}

				//如果重新加载TEMPLAT或XML,则重新加载数据对象.
				FormDataLoadWorker.initDataObjectOnLoad(form);
				//CID 0128 //2008.09.29 //Begin
				//只生成JetId,用于FormCalculatedFieldWorker中.
				//FormBuildFieldListByXMLDocWorker.buildFieldListByXMLDoc(form,true);
				//FormCodeDispatchWorker.OnLoad(form);
				//FormRuleOnLoadWorker.onLoad(form);
				//CID 0128 //2008.09.29 //End
			}
			else
			{
				//否则从SessionCache中取出.
				FormDataLoadWorker.reloadDataObject(form);
			}

			//恢复BASE64内容，这个操作涉及三个地方：
			//1. ExtXdImageFunction, 2. XFileAttachmentEncoder XImageEncoder, 3. PostedFileEncodeWorker.
			//对应恢复BASE64之后,要正常显示必需再缓存BASE64内容.
			//缓存BASE64内容后,因为XML中的结点值已经被修改成xdInlineFile:filePath,所以还应该再修改成BASE64.
            //CID 0618 //2010.07.05 //isInlineFileEnabled
			if( ( form.Command.Equals( JetConstant.CMD_BUILD_BY_PARAMETERS ) ||
			      form.Command.Equals( JetConstant.CMD_UPDATE_Submit ) ||
				  form.Command.Equals( JetConstant.CMD_UPDATE_Button ) 
                ) && InlineFileUtil.isInlineFileEnabled(form))
			{
				//如果正在保存表单，从磁盘上恢复附件，图片。
				XFileAttachmentEncoder.restoreFiles( form );
				XImageEncoder.restoreImages( form );
			}
			
			if (form.Command.Equals( JetConstant.CMD_UPDATE_XmlToEdit )) 
			{
				string xmlToEditName = (string) form.ParamTable[JetConstant.XDOC_PARAM_XML_TO_EDIT_NAME];
				string xmlToEditAction = (string) form.ParamTable[JetConstant.XDOC_PARAM_XML_TO_EDIT_ACTION];
				string contextIdArray = (string) form.ParamTable[JetConstant.XDOC_PARAM_CONTEXT_ID_ARRAY];
				XmlXmlToEditWorker.doXmlToEditAction(form, xmlToEditName, xmlToEditAction, contextIdArray);
			}
			else if (form.Command.Equals( JetConstant.CMD_UPDATE_Query ))
			{
                //CID 1142 //2012.03.20 //Begin
				FormDataQueryWorker.query(form, false);
                //CID 1142 //2012.03.20 //End
			}
			else if (form.Command.Equals( JetConstant.CMD_UPDATE_New ))
			{
				FormDataNewWorker.newData(form);
			}
			else if (form.Command.Equals( JetConstant.CMD_UPDATE_Refresh ))
			{
				string auxDom = (string) form.ParamTable[JetConstant.XDOC_PARAM_AUXDOM];
				FormDataRefreshWorker.refresh(form,auxDom);
			}
			else if (form.Command.Equals( JetConstant.CMD_UPDATE_Submit ))
			{
                //CID 0859 //2012.03.20 //Begin
                //CID 1143 //2012.03.21 //Begin
				FormDataSubmitWorker.submit(form, false, false);
                //CID 1143 //2012.03.21 //End
                //CID 0859 //2012.03.20 //End
			}
			else if (form.Command.Equals( JetConstant.CMD_UPDATE_Button ))
			{
				//如果是点击了按钮,执行按钮上定义的Rules和OnClick,先Rules后OnClick,顺序测试见Rules and Custom Code.xsn
				//取得按钮ID,就是xd:CtrlId属性.
				string buttonId = (string) form.ParamTable[JetConstant.XDOC_PARAM_BUTTON];
				//CID 0335 //2009.06.22 //Begin
				if( buttonId.Equals( JetConstant.INNER_EXPORT_MHT_BUTTON ) )
				{
                    //CID 0711 //2010.12.03 //Begin
                    if (ConfigUtil.ExportPrintablePDF())
                    {
                        FormExportPrintableVersionWorker.exportPrintableVersionWorker(form, "pdf");
                    }
                    else
                    {
                        FormExportPrintableVersionWorker.exportPrintableVersionWorker(form, "mht");
                    }
                    //CID 0711 //2010.12.03 //End
				}
				else if( buttonId.Equals( JetConstant.INNER_EXPORT_HTML4FF_BUTTON ) )
				{
					form.JetContext.ExportPrintableHtml4FF = true;
					FormExportPrintableVersionWorker.exportPrintableVersionWorker(form, "htm");
				}
				//CID 0335 //2009.06.22 //End
				else
				{
					//取得buttonSource,buttonSource是Xml上下文的NodeId.
					string buttonSource = (string) form.ParamTable[JetConstant.XDOC_PARAM_BUTTON_SOURCE];
					//执行Rules
					FormRuleButtonWorker.runRule(form,buttonId,buttonSource);
					//执行OnClick Code.
					FormCodeDispatchWorker.OnClick(form,buttonId,buttonSource);
				}
			}
            //CID 0656 //2010.10.22 //Begin
            else if (form.Command.Equals(JetConstant.CMD_UPDATE_AddPrincipals))
            {
                PNGAddPrincipalsWorker.addPrincipals(form);
            }
            //added by lishuchao 2011.11.10 //Begin
            else if (form.Command.Equals(JetConstant.CMD_UPDATE_UpdatePrincipals))
            {
                PNGUpdatePrincipalsWorker.updatePrincipals(form);
            }
            //added by lishuchao 2011.11.10 //end
            else if (form.Command.Equals(JetConstant.CMD_UPDATE_DeletePrincipal))
            {
                PNGDeletePrincipalWorker.deletePrincipal(form);
            }
            //CID 0656 //2010.10.23 //End
            //CID 0657 //2010.12.09 //Begin
            else if (form.Command.Equals(JetConstant.CMD_UPDATE_AddEXIItems))
            {
                EXIAddItemsWorker.addItems(form);
            }
            else if (form.Command.Equals(JetConstant.CMD_UPDATE_DeleteEXIItem))
            {
                EXIDeleteItemWorker.deleteItem(form);
            }
            //CID 0657 //2010.12.15 //End
            //CID 0749 //2011.09.01 //Begin
            else if (form.Command.Equals(JetConstant.CMD_UPDATE_AddSignature))
            {
                DigitalSignatureAddWorker.addSignature(form);
            }
            else if (form.Command.Equals(JetConstant.CMD_UPDATE_DeleteSignature))
            {
                DigitalSignatureDeleteWorker.deleteSignature(form);
            }
            //CID 0749 //2011.09.16 //End
            else if (form.Command.Equals(JetConstant.CMD_BUILD_BY_PARAMETERS))
            {
                //只有保存的时候才使用CMD_BUILD_BY_PARAMETERS命令.
                ManagedCodeOnSaveFormWorker.OnSaveForm(form);
            }

			//构造视图.
			FormManager.buildFormView(form);
		}
		
		//这是一个除了CMD_UPDATE_File之外其它命令都要调用的方法,要慎重修改.
		//用于重新构造表单视图内容.
		private static void buildFormView(Form form)
		{
			//这段不能移动,buildFormView也被buildFormByTemplate和buildFormByXML使用.
			if( form.Command.Equals( JetConstant.CMD_BUILD_BY_TEMPLATE ) || 
				form.Command.Equals( JetConstant.CMD_BUILD_BY_XML ) )
			{
				FormBuildFieldListByXMLDocWorker.buildFieldListByXMLDoc(form,true);//只生成JetId,用于FormCalculatedFieldWorker中.
				//CID 0143 //2008.10.17 //Begin
				//CID 0217 //2009.01.30 //Begin
				FormCalculatedFieldWorker.calculateFields(form);
				FormRuleOnLoadWorker.onLoad(form);
				FormCodeDispatchWorker.OnLoad(form);
				//CID 0217 //2009.01.30 //End
				//CID 0143 //2008.10.17 //End
			}
			//CID 0473 //2009.12.14 //Begin
			//如果是因为RefreshAfterUpdate(CodeNode)进行刷新
			//ValueChangeId和ValueChangeNode已经在FormDeformatChangedNodeValueWorker中设置.
			//FormDeformatChangedNodeValueWorker在FormBuildXMLDocByFieldListWorker中调用.
			else if( form.Command.Equals( JetConstant.CMD_UPDATE_Refresh ) && form.ValueChangeNode != null )
			{
				FormRuleFieldWorker.runRule(form);		//Rule
				//CID 0473 //2009.12.14 //Begin
				FormCalculatedFieldWorker.calculateFields(form);
				//CID 0473 //2009.12.14 //End
				//此时是由RefreshAfterUpdate进行刷新,由值改变引起,Site和Source不同,Source应该是值结点,一般是text结点..
				string path = DOMUtil.getNodePath( form.ValueChangeNode );
				FormCodeDispatchWorker.OnAfterChange( form, path, form.ValueChangeNode, FormCodeDispatchWorker.Updated, true );
			}
			else
			{
				FormCalculatedFieldWorker.calculateFields(form);
			}
			//CID 0473 //2009.12.14 //End

			//CID 0127 //2008.09.29 //Begin
			FormSession.updateDataTable( form );
			//CID 0127 //2008.09.29 //End

			//准备要输出的视图，并在其中触发OnSwitchView事件。
			FormPrepareViewWorker.prepareView( form );

			//在buildFieldListByXMLDoc之前缓存表单.
			//如果正在打开表单，或曾经恢复过，再将附件、图片缓存到磁盘上。
			//CID 0412 //2009.10.12 //form.ChangedBase64NodeList
            //CID 0618 //2010.07.05 //isInlineFileEnabled
			if( ( FormUtil.isOpeningForm( form ) || form.RestoredBASE64NodeTable != null || form.ChangedBase64NodeList != null )
                && InlineFileUtil.isInlineFileEnabled(form))
			{
				XFileAttachmentDecoder.cacheFiles( form );
				XImageDecoder.cacheImages( form );
			}

			//在这个方法调用中赋予JetId.
			FormBuildFieldListByXMLDocWorker.buildFieldListByXMLDoc(form, false);//同时生成JetId
			//在此之后Xml节点JetId已经被刷新，同时各个字段的值已经缓存到FieldList中，如果在此后修改它们，必需同时更新FieldList中的值。

			//FieldList已经生成，表单DOM成为只读，尤其是在OnValidate事件中。测试表单见EnableNodeValueTrigger.xsn。
			form.IsDomReadonly = true;

            //CID 0778 //2011.03.28 //Begin
			FormRunSchemaValidationWorker.runSchemaValidation(form);
			FormRunErrorConditionWorker.runErrorCondition(form);
            //所有的OnValidate都只发送Updated操作,这样可以节省性能(减少一次调用),在InfoPath中是根据情况发送Delete和Insert.
            FormCodeDispatchWorker.OnValidate(form, FormCodeDispatchWorker.Updated);
            //CID 0778 //2011.03.28 //End
			
			//CID 0543 //2010.04.30 //Begin
			//最后检查一下View是否存在。
			//这里主要是对ValueChange进行处理，以为ValueChange没有调用buildFormView()->prepareView()。
			//这部分代码来自FormBuildHTMLDocWorker，提前是为了方便FormBuildXmlToEditFieldsWorker中使用form.View。
			if( form.View == null )
			{
				View view = form.Manifest.getView(form.ViewId);
				if (view == null)
				{
					throw new InfoJetException("no view " + form.ViewId, "FBHD01");
				}
				form.View = view;
			}
            
			//CID 0543 //2010.04.30 //End

			FormBuildComponentIdListWorker.buildComponentIdList(form);
			FormBuildXmlToEditFieldsWorker.buildXmlToEditFields(form);
			FormBuildMaxLengthValueWorker.buildMaxLengthValue(form);

			//Build HTML Doc.
			FormBuildHTMLDocWorker.buildHTMLDoc(form);
            //CID 0827 //2011.03.07 //Begin
            FormFormatHtmlDocWorker.formatHtmlDoc(form);
            //CID 0827 //2011.03.07 //End
            //CID 0078 //2008.08.13 //Begin
			//不需要在ValueChange中调用,因为ValueChange不会更新src.
			//CID 0078 //2008.08.13 //End
			//输出表单.
			FormExportHtmlViewWorker.exportHtmlView( form );
			FormAutoFocusWorker.autoFocus( form );

			FormBuildHTMLFormWorker.buildHTMLForm(form);
			FormBuildHTMLDataWorker.buildHTMLData(form);
			FormBuildHTMLIFrameWorker.buildHTMLIFrame(form);
			FormBuildHTMLScriptWorker.buildHTMLScript(form);
			FormFormatEmptyElementWorker.formatEmptyElement(form);

            //CID 0664 //2010.10.05 //Begin
            FormManager.cacheFormXml(form);
            //CID 0664 //2010.11.24 //End

			//从CachedBASE64NodeTable中恢复BASE64内容,保证传出的Xml文档是正常的.
			if( form.CachedBASE64NodeTable != null )
			{
				foreach( System.Xml.XmlNode node in form.CachedBASE64NodeTable.Keys )
				{
					string nodeValue = form.CachedBASE64NodeTable[ node ] as string;
					DOMUtil.setNodeValue( node, nodeValue );
				}
			}
		}

        //CID 0664 //2010.10.05 //Begin
        private static void cacheFormXml(Form form)
        {
            if (form.Manifest.FormFieldsCacheEnabled)
            {
                FormSession.updateFormXml(form);
                XmlElement formElement = (XmlElement)form.HtmlDoc.DocumentElement.SelectSingleNode("/div/div[@id='" + JetConstant.FormId + "']");
                foreach (XmlElement fieldHTMLElement in form.FormFieldHTMLElementList)
                {
                    //CID 0664 //2010.11.24 //Begin
                    if (!fieldHTMLElement.Name.Equals(JetConstant.HTML_textarea))
                    {
                        formElement.RemoveChild(fieldHTMLElement);
                    }
                    //CID 0664 //2010.11.24 //End
                }
            }
        }
        //CID 0664 //2010.10.05 //End

		//CID 0352 //2009.07.06 //Begin
		public static string BuildNonDirtyFormXml( HttpContext httpContext, InfoJetContext jetContext, Hashtable paramTable )
		{
			Form form = new Form();
			form.HttpContext = httpContext;
			form.JetContext = jetContext;
			form.ParamTable = paramTable;

			//CID 0331 //2009.07.27 //Begin
			FormLoadManifestWorker.loadManifest(form);
			FormParseRequestParamWorker.parseRequestParam(form);
			//CID 0331 //2009.07.27 //End
			FormBuildXMLDocByFieldListWorker.buildNonDirtyXMLDocByFieldList(form);

            //CID 0618 //2010.07.05 //isInlineFileEnabled
            if (InlineFileUtil.isInlineFileEnabled(form))
			{
				//如果正在保存表单，从磁盘上恢复附件，图片。
				XFileAttachmentEncoder.restoreFiles( form );
				XImageEncoder.restoreImages( form );
			}

			DOMUtil.removeJetId( form.XmlDoc );
			return DOMUtil.toString( form.XmlDoc );
		}
		//CID 0352 //2009.07.06 //End
	}
}
